package com.bytebuddytest.fieldandmethod;

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.implementation.FixedValue;
import org.junit.Assert;
import org.junit.Test;

import static net.bytebuddy.matcher.ElementMatchers.isDeclaredBy;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;

/**
 * @author yutianhong
 * @version 1.0
 * @since 2023/09/25 19:49
 */
public class MethodMatcherTest {

    @Test
    public void testStackMatchers() throws InstantiationException, IllegalAccessException {
        Foo dynamicFoo = new ByteBuddy()
                .subclass(Foo.class)
                .method(isDeclaredBy(Foo.class)).intercept(FixedValue.value("One!"))
                .method(named("foo")).intercept(FixedValue.value("Two!"))
                .method(named("foo").and(takesArguments(1))).intercept(FixedValue.value("Three!"))
                .make()
                .load(getClass().getClassLoader())
                .getLoaded()
                .newInstance();
        Assert.assertEquals(dynamicFoo.bar(), "One!");
        Assert.assertEquals(dynamicFoo.foo(), "Two!");
        Assert.assertEquals(dynamicFoo.foo(null), "Three!");
    }

    @Test
    public void testIgnoreMethod() throws InstantiationException, IllegalAccessException {
        Foo dynamicFoo = new ByteBuddy()
                .subclass(Foo.class)
                .method(isDeclaredBy(Foo.class)).intercept(FixedValue.value("One!"))
                .method(named("foo")).intercept(FixedValue.value("Two!"))
                .ignoreAlso(named("foo").and(takesArguments(1)))
                .make()
                .load(getClass().getClassLoader())
                .getLoaded()
                .newInstance();
        Assert.assertEquals(dynamicFoo.bar(), "One!");
        Assert.assertEquals(dynamicFoo.foo(), "Two!");
        Assert.assertNotEquals(dynamicFoo.foo(null), "One!");
        Assert.assertNotEquals(dynamicFoo.foo(null), "Two!");
    }

}
